package fuck.loader;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.eclipse.ui.console.MessageConsoleStream;

import fuck.ActionContext;
import fuck.bean.Datas;
import fuck.bean.Field;

public class ExcelLoader
{
  public ArrayList<Datas> load(ActionContext context, String fileName, boolean dataLoad)
  {
    ArrayList result = new ArrayList();

    int currentRow = 0;

    int currentCell = 0;
    try
    {
      FileInputStream in = new FileInputStream(fileName);

      XSSFWorkbook wb = new XSSFWorkbook(in);

      XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(wb);

      int sheetNumber = wb.getNumberOfSheets();
      for (int i = 0; i < sheetNumber; i++)
      {
        XSSFSheet sheet = wb.getSheetAt(i);

        if ((sheet.getSheetName() != null) && (!"changelog".equals(sheet.getSheetName())) && (sheet.getSheetName().indexOf("说明") == -1))
        {
          String name = sheet.getSheetName();

          Datas datas = new Datas();

          datas.setFilename(fileName);
          datas.setName(name);

          String[][] fields = new String[5][];

          XSSFRow row = sheet.getRow(4);
          int cellNumber = row.getPhysicalNumberOfCells();

          for (int j = 0; j < 5; j++) {
            currentRow = j;
            row = sheet.getRow(j);
            if (row != null) {
              fields[j] = new String[cellNumber];
              for (int k = 0; k < cellNumber; k++) {
                currentCell = k;
                XSSFCell cell = row.getCell(k);
                if (cell != null)
                  fields[j][k] = cell.toString();
              }
            }
          }
          for (int j = 0; j < fields[0].length; j++)
          {
            if ((fields[1][j] != null) && (!"".equals(fields[1][j].trim())))
            {
              Field field = new Field();
              field.setName(fields[1][j].trim());
              if ((fields[2] == null) || (fields[2][j] == null) || ("".equals(fields[2][j].trim()))) {
                field.setClassName("int");
                field.setJavaClassName("int");
                field.setDbClassName("INTEGER");
              } else {
                field.setClassName(fields[2][j].trim());
                if (fields[2][j].trim().indexOf("varchar") != -1) {
                  field.setJavaClassName("String");
                  field.setDbClassName("VARCHAR");
                } else if (fields[2][j].trim().indexOf("bigint") != -1) {
                  field.setJavaClassName("long");
                  field.setDbClassName("BIGINT");
                } else if (fields[2][j].trim().indexOf("smallint") != -1) {
                  field.setJavaClassName("short");
                  field.setDbClassName("SMALLINT");
                } else if (fields[2][j].trim().indexOf("tinyint") != -1) {
                  field.setJavaClassName("byte");
                  field.setDbClassName("TINYINT");
                } else if (fields[2][j].trim().indexOf("int") != -1) {
                  field.setJavaClassName("int");
                  field.setDbClassName("INTEGER");
                } else if (fields[2][j].trim().indexOf("blob") != -1) {
                  field.setJavaClassName("byte[]");
                  field.setDbClassName("LONGVARBINARY");
                } else if (fields[2][j].trim().indexOf("text") != -1) {
                  field.setJavaClassName("String");
                  field.setDbClassName("LONGVARCHAR");
                }
              }
              field.setExplain(fields[4][j]);
              field.setCell(j);

              if ((fields[0].length > j) && (fields[0][j] != null) && (!"".equals(fields[0][j].trim())) && 
                ((int)Double.parseDouble(fields[0][j]) == 1)) {
                datas.getKeys().add(field);
                datas.setKey(field);
              }

              datas.getFields().add(field);
            }
          }

          if (datas.getKeys().size() > 1)
          {
            Field field = new Field();

            StringBuffer buf = new StringBuffer();
            for (int j = 0; j < datas.getKeys().size(); j++) {
              buf.append("_" + fields[1][((Field)datas.getKeys().get(j)).getCell()]);
            }
            if (buf.length() > 0) buf.deleteCharAt(0);
            field.setName(buf.toString());
            field.setClassName("varchar(255)");
            field.setDbClassName("VARCHAR");
            field.setJavaClassName("String");
            buf = new StringBuffer();
            for (int j = 0; j < datas.getKeys().size(); j++) {
              buf.append("+" + fields[4][((Field)datas.getKeys().get(j)).getCell()]);
            }
            if (buf.length() > 0) buf.deleteCharAt(0);
            field.setExplain(buf.toString());
            field.setCell(-1);
            datas.getFields().add(0, field);

            datas.setKey(field);
          }

          if ((dataLoad) && (sheet.getPhysicalNumberOfRows() > 5)) {
            String[][] data = new String[sheet.getPhysicalNumberOfRows() - 5][datas.getFields().size()];
            for (int j = 5; j < sheet.getPhysicalNumberOfRows(); j++) {
              currentRow = j;
              row = sheet.getRow(j);
              if (row != null) {
                for (int k = 0; k < datas.getFields().size(); k++) {
                  currentCell = k;
                  Field field = (Field)datas.getFields().get(k);
                  if (field.getCell() == -1) {
                    StringBuffer buf = new StringBuffer();
                    for (int l = 0; l < datas.getKeys().size(); l++) {
                      XSSFCell cell = row.getCell(((Field)datas.getKeys().get(l)).getCell());
                      if (cell.getCellType() == 2) {
                        buf.append("_" + String.valueOf((int)evaluator.evaluate(cell).getNumberValue()));
                      }
                      else if (("int".equals(((Field)datas.getKeys().get(l)).getClassName())) || ("bigint".equals(((Field)datas.getKeys().get(l)).getClassName())) || ("smallint".equals(((Field)datas.getKeys().get(l)).getClassName())) || ("tinyint".equals(((Field)datas.getKeys().get(l)).getClassName())))
                        buf.append("_" + String.valueOf(cell.getNumericCellValue()));
                      else {
                        buf.append("_" + cell.toString().trim());
                      }
                    }

                    if (buf.length() > 0) buf.deleteCharAt(0);
                    data[(j - 5)][k] = buf.toString();
                  } else {
                    XSSFCell cell = row.getCell(field.getCell());
                    if ((cell == null) || ("".equals(cell.toString().trim()))) {
                      if (("int".equals(field.getClassName())) || ("bigint".equals(field.getClassName())) || ("smallint".equals(field.getClassName())) || ("tinyint".equals(field.getClassName())))
                        data[(j - 5)][k] = "0";
                      else
                        data[(j - 5)][k] = "";
                    }
                    else if (cell.getCellType() == 2) {
                      data[(j - 5)][k] = String.valueOf((int)evaluator.evaluate(cell).getNumberValue());
                    }
                    else if (("int".equals(field.getClassName())) || ("bigint".equals(field.getClassName())) || ("smallint".equals(field.getClassName())) || ("tinyint".equals(field.getClassName())))
                      data[(j - 5)][k] = String.valueOf(cell.getNumericCellValue());
                    else {
                      data[(j - 5)][k] = cell.toString().trim();
                    }
                  }
                }
              }
            }

            datas.setDatas(data);
          }
          result.add(datas);
        }
      }

      in.close();
    } catch (FileNotFoundException e) {
      context.getMcs().println(e.getMessage());
    } catch (IOException e) {
      context.getMcs().println(e.getMessage());
    } catch (Exception e) {
      context.getMcs().println(currentRow + "," + currentCell + ":" + e.getMessage());
    }
    return result;
  }
}
